#include "widget.h"
#include "ui_widget.h"
#include"check.h"
#include <QTcpSocket>
#include <QTcpServer>
#include <string.h>
#include <QSqlDatabase>
#include <QDebug>
#include <QMessageBox>
#include <QSqlError>
#include <QSqlQuery>
#include <QThread>
#include <windows.h>
#include <fstream>
#include <QNetworkAccessManager>


//定义全局变量,方便使用
MyXml xml; //全局请求xml对象
MyMsg MyMsg;//全局消息对象
bool IfStart = false;
bool ROBOTREPLY = false;
QSqlDatabase MyDataBase =  QSqlDatabase::addDatabase("QMYSQL");
//定义mysql数据库信息
const QString DbHost= "39.107.233.149" ;
const QString DbUserName = "xxq";
const QString DbPassWord = "xiao3344520";
const QString DbDataBaseName = "xxq";

const int DataSize = 20;  //建议debug打印的时候带上行数,不然找得头疼,嘤嘤嘤
//QSqlDatabase MyDataBase =  QSqlDatabase::addDatabase("QMYSQL");
//MyDataBase.setHostName("39.107.233.149");
//MyDataBase.setUserName("xxq");
//MyDataBase.setPassword("xiao3344520");
//MyDataBase.setDatabaseName("xxq");

//写入日志文件
void WFileLog(QString x)
{
  using namespace  std;
  ofstream LogFile("./log.txt");
  LogFile<<x.toStdString()+"\n";
  LogFile.close();
}

//读出日志文件
QString RFileLog()
{
    using namespace  std;
    string data;
ifstream LogFile("./log.txt");
LogFile>>data;
LogFile.close();
return QString::fromStdString(data);
}

//从数据库获取回复消息对象
void GetMsgFromDataBase(QString x)
{
    QString res;
    MyDataBase.setHostName("39.107.233.149");
    MyDataBase.setUserName("xxq");
    MyDataBase.setPassword("xiao3344520");
    MyDataBase.setDatabaseName("xxq");
    //打开数据库
    if(!MyDataBase.open()){
         //数据库打开失败
          Widget *temp = new Widget;
          QMessageBox::warning(temp,"错误",MyDataBase.lastError().text());
    }else{
        QSqlQuery Query("SELECT * FROM `msg` WHERE `gettext` LIKE '%"+x+"%' ");
         while(Query.next()){
//            qDebug()<<Query.value(2).toString()<<endl;
//           res = Query.value(2).toString();
             int i = 0;
             for(i=0;i<9;i++){
                MyMsg.Data[i] = Query.value(i).toString();
             }
         }
    }
}

//配置数据库相关
void Widget::StartMySql()
{
//    this->MyDataBase->setHostName(DbHost);
//    this->MyDataBase->setUserName(DbUserName);
//    this->MyDataBase->setPassword(DbPassWord);
//    this->MyDataBase->setDatabaseName(DbDataBaseName);

}
//其他函数
//控制台打印提示信息
void Att(int Line)
{
qDebug()<<QString::fromStdString(std::to_string(Line))+"行"<<endl;
}

//提取出消息的创建时间
void ClearCreateTime(MyXml &x){
  std::string temp = x.Data[8].toStdString();
  int i = 0;
std::string temp2;
  while(temp[i])
  {
      if(temp[i]=='<')
      {
          break;
      }
      temp2 = temp2 + temp[i];
      i++;
  }
  x.Data[8] = QString::fromStdString(temp2);
}

//展示消息内容
void MyMsg::ShowMyMsg()
{
    int i = 0;
    while(this->Data[i].length())
    {
         qDebug()<<Data[i]<<endl;
    }

}

//从数据库获取数据来进行回复
QString GetDataFromDataBase(QString x)
{
    QString res;

    MyDataBase.setHostName("39.107.233.149");
    MyDataBase.setUserName("xxq");
    MyDataBase.setPassword("xiao3344520");
    MyDataBase.setDatabaseName("xxq");
    //打开数据库
    if(!MyDataBase.open()){
         //数据库打开失败
        Widget *temp = new Widget;
          QMessageBox::warning(temp,"错误",MyDataBase.lastError().text());
    }else{
        QSqlQuery Query("SELECT * FROM `msg` WHERE `gettext` LIKE '%"+x+"%' ");
         while(Query.next()){
//            qDebug()<<Query.value(2).toString()<<endl;
           res = Query.value(2).toString();
         }
    }
    std::string temp = res.toStdString();
    if(temp.length()==0)
    {
        temp = "null"; //返回null,表示没有匹配信息
    }
//    qDebug()<<res<<endl;
    return QString::fromStdString(temp);
}


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->StartMySql(); //初始化数据库
//    ui->pushButton_2->setDisabled(true);
    ui->pushButton_3->setDisabled(true);
    //监听socket
         TcpServer = new QTcpServer(this); //指定父对象自动回收空间
         connect(TcpServer,&QTcpServer::newConnection,this,[=](){
         Tcp = TcpServer->nextPendingConnection();
        //监测是否可以接受数据
          connect(Tcp,&QTcpSocket::readyRead,this,[=](){
          QString data = Tcp->readAll();
          ui->MsgBox->append(data);
          QString res = Widget::GetXmlData(data);
          xml = GetXmlEle(res);
          ui->MsgBox->append("消息类型: "+GetMsgType(xml));
          this->on_pushButton_2_clicked(); //开启回复
          if(GetMsgType(xml)=="text")
          {
              ui->MsgBox->append("消息内容: "+xml.GetMsg());
          }else{
              ui->MsgBox->append("不支持展示的消息类型!"+GetMsgType(xml));
          }
//          ui->MsgBox->append("数据库消息"+GetDataFromDataBase("test"));
      });
     });
}

Widget::~Widget()
{
    delete ui;
}

//监听端口
void Widget::on_pushButton_clicked()
{

      TcpServer->listen(QHostAddress::Any,80);//监听端口
      ui->MsgBox->append("开始监听80端口,请注意");
      ui->pushButton->setDisabled(true);
      ui->pushButton_3->setDisabled(false);


}

//发送消息
void Widget::on_pushButton_2_clicked()
{
  this->ToReply();
}


//回复文本消息
void Widget::SendTextMsg(QString x = "我还不知道怎么回复哦,我会努力学习的!!!")
{
   QString Msg = x;
 //   qDebug()<<Msg<<endl;
  QString Reply = MyXml::GetTextReplyXml(Msg);
//   qDebug()<<Reply<<endl;//查看输入框数据是否获取到
  QByteArray response =Reply.toUtf8();
  QString http = "HTTP/1.1 200 OK\r\n";
  http += "Server: nginx\r\n";
//     http += "Content-Type: text/html;charset=utf-8\r\n"; //返回html
  http += "Content-Type:text/xml;charset=utf-8\r\n";//返回xml格式
  http += "Connection: keep-alive\r\n";
  http += QString("Content-Length: %1\r\n\r\n").arg(QString::number(response.size()));
  Tcp->write(http.toUtf8());
  Tcp->write(response);
  Tcp->flush();
  Tcp->waitForBytesWritten(http.size() + response.size());
  Tcp->close();
  ui->MsgBox->append("服务器说:"+Msg.toUtf8());
}

void Widget::SendMsg(QString xml)
{
    QString Reply = xml;
   QByteArray response =Reply.toUtf8();
   QString http = "HTTP/1.1 200 OK\r\n";
   http += "Server: nginx\r\n";
 //     http += "Content-Type: text/html;charset=utf-8\r\n"; //返回html
   http += "Content-Type:text/xml;charset=utf-8\r\n";//返回xml格式
   http += "Connection: keep-alive\r\n";
   http += QString("Content-Length: %1\r\n\r\n").arg(QString::number(response.size()));
   Tcp->write(http.toUtf8());
   Tcp->write(response);
   Tcp->flush();
   Tcp->waitForBytesWritten(http.size() + response.size());
   Tcp->close();
   ui->MsgBox->append("服务器说:"+xml.toUtf8());
}
//关闭
void Widget::on_pushButton_3_clicked()
{
   Tcp->close();
   ui->pushButton->setDisabled(false);
//   ui->pushButton_2->setDisabled(true);
   ui->MsgBox->append("关闭连接");
}

//清空消息
void Widget::on_pushButton_4_clicked()
{
  ui->MsgBox->clear();
}


//从请求消息中提取xml数据
QString Widget::GetXmlData(QString OldData)
{
    std::string temp = OldData.toStdString();
    bool flag = false;
    std::string res;
    int i = 0;
    while(temp[i])
    {
     if(temp[i]=='<'&&temp[i+1]=='x'){
         flag = true;
     }
     if(flag)
     {
         res = res + temp[i];
     }
     i++;
    }
    QString res2 = QString::fromStdString(res);
//    qDebug()<<res2<<endl;
  return  res2;
}

//初始化xml
MyXml::MyXml(QString x[256])
{
    int i = 0;
    while(x[i]!="\0"){
     this->Data[i] = x[i];
      i++;
  }
}

//初始化xml
void MyXml::Start(QString *x){
    int i = 0;
    while(x[i]!="\0"){
     this->Data[i] = x[i];
      i++;
  }
}

//使用QString数据来初始化xml,生成xml数组数据项,返回已经初始化好的对象
MyXml GetXmlEle(QString OldData)
{
  std::string temp = OldData.toStdString();
  std::string res[DataSize];
  int  tempnum = 0;
  int i = 0;
  while(temp[i]){
     if(temp[i-1]=='>'){
        tempnum++;
     }
     res[tempnum] = res[tempnum]+temp[i];
    i++;
  }
  QString res2[DataSize];
  for(int j = 0;res[j][0];j++){
    res2[j] = QString::fromStdString(res[j]);
  }
  MyXml x(res2);
//  x.ShowMyData();
  return x;
}

//复制构造函数
MyXml::MyXml(MyXml &x)
{
    for(int i = 0;i<256;i++)
    {
        this->Data[i] = x.Data[i];
    }
}

//打印出自己的数据
void MyXml::ShowMyData()
{
  for(int i = 0;i<DataSize;i++)
  {
  qDebug()<<this->Data[i]<<endl;
  }
}
//获取消息本息
QString MyXml::GetMsg()
{
   std::string temp = this->Data[13].toStdString();
   int i = 0;
   bool flag = false;
   std::string res;
   while(temp[i])
   {
       if(temp[i-2]=='A'&&temp[i-1]=='['){
           flag = true;
       }
       if(flag)
       {
           res = res + temp[i];
       }
       if(temp[i+1]==']')
       {
           break;
       }
      i++;
   }
   return  QString::fromStdString(res);
}

//无参构造函数
MyXml::MyXml(){
//
}

//获取请求消息的类型
QString GetMsgType(MyXml &m)
{
 std::string temp = m.Data[10].toStdString();
 int i = 0;
 bool flag = false;
 std::string res;
 while(temp[i])
 {
     if(temp[i-2]=='A'&&temp[i-1]=='['){
         flag = true;
     }
     if(flag)
     {
         res = res + temp[i];
     }
     if(temp[i+1]==']')
     {
         break;
     }
    i++;
 }
 //返回数据类型
 return QString::fromStdString(res);
}

//返回文本消息回复xml
QString MyXml::GetTextReplyXml(QString y)
{
 std::string res;
 /*
  *
  <xml>
  <![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>12345678</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[你好]]></Content>
  </xml>
  */
 xml.ShowMyData();
 ClearCreateTime(xml);
 std::string temp1 = xml.Data[5].toStdString();
 std::string temp2 = xml.Data[2].toStdString();
 std::string temp3 = xml.Data[8].toStdString();
 std::string temp4 = xml.Data[10].toStdString();
 std::string temp5 = y.toStdString();
 res ="<xml><ToUserName>"+temp1+"</ToUserName>"+"<FromUserName>"+temp2+"</FromUserName>"+"<CreateTime>"+temp3+"</CreateTime>"+"<MsgType>"+temp4+"</MsgType><Content><![CDATA["+temp5+"]]></Content></xml>";
//  res = res + "<FromUserName>"+x.Data[1]+"</FromUserName>";
//  res = res + "<CreateTime>"+x.Data[7]+"</CreateTime>";
//  res = res + "<MsgType>"+x.Data[10]>+"</MsgType>";
//  res = res + " <Content><![CDATA["+y+"]]></Content>";
//  qDebug()<<res<<endl;
//  xml.ShowMyData();
  qDebug()<<QString::fromStdString(res)<<endl;
 return QString::fromStdString(res);
}


//返回回复图片xml数据  id为素材库的素材id
QString MyXml::GetImgReplyXml(QString id)
{
 /*
     <xml>
      <ToUserName><![CDATA[toUser]]></ToUserName>
      <FromUserName><![CDATA[fromUser]]></FromUserName>
      <CreateTime>12345678</CreateTime>
      <MsgType><![CDATA[image]]></MsgType>
      <Image>
        <MediaId><![CDATA[media_id]]></MediaId>
      </Image>
    </xml>

*/

 std::string res;
 xml.ShowMyData();
 ClearCreateTime(xml);
 std::string temp1 = xml.Data[5].toStdString();
 std::string temp2 = xml.Data[2].toStdString();
 std::string temp3 = xml.Data[8].toStdString();
// std::string temp4 = xml.Data[10].toStdString();
 std::string temp5 = id.toStdString();
 res ="<xml><ToUserName>"+temp1+"</ToUserName>"+"<FromUserName>"+temp2+"</FromUserName>"+"<CreateTime>"+temp3+"</CreateTime>"+"<MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA["+temp5+"]]></MediaId></Image></xml>";
 qDebug()<<QString::fromStdString(res)<<endl;
 return QString::fromStdString(res);
}


//返回语音消息的xml数据
QString MyXml::GetVoiceReplyXml(QString id)
{

    std::string res;
    xml.ShowMyData();
    ClearCreateTime(xml);
    std::string temp1 = xml.Data[5].toStdString();
    std::string temp2 = xml.Data[2].toStdString();
    std::string temp3 = xml.Data[8].toStdString();
   // std::string temp4 = xml.Data[10].toStdString();
    std::string temp5 = id.toStdString();
    res ="<xml><ToUserName>"+temp1+"</ToUserName>"+"<FromUserName>"+temp2+"</FromUserName>"+"<CreateTime>"+temp3+"</CreateTime>"+"<MsgType><![CDATA[voice]]></MsgType><Voice><MediaId><![CDATA["+temp5+"]]></MediaId></Voice></xml>";
    qDebug()<<QString::fromStdString(res)<<endl;
    return QString::fromStdString(res);
}

/*
 *
 * <xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>12345678</CreateTime>
  <MsgType><![CDATA[video]]></MsgType>
  <Video>
    <MediaId><![CDATA[media_id]]></MediaId>
    <Title><![CDATA[title]]></Title>
    <Description><![CDATA[description]]></Description>
  </Video>
</xml>

*/
//返回回复视频消息的xml数据
QString MyXml::GetVideoReplyXml(QString id, QString title="视频消息", QString description="视频消息")
{
    std::string res;
    xml.ShowMyData();
    ClearCreateTime(xml);
    std::string temp1 = xml.Data[5].toStdString();
    std::string temp2 = xml.Data[2].toStdString();
    std::string temp3 = xml.Data[8].toStdString();
    std::string temp6 = title.toStdString();
    std::string temp7 = description.toStdString();
   // std::string temp4 = xml.Data[10].toStdString();
    std::string temp5 = id.toStdString();
    res ="<xml><ToUserName>"+temp1+"</ToUserName>"+"<FromUserName>"+temp2+"</FromUserName>"+"<CreateTime>"+temp3+"</CreateTime>"+"<MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA["+temp5+"]]></MediaId> <Title><![CDATA["+temp6+"]]></Title><Description><![CDATA["+temp7+"]]></Description></Video></xml>";
    qDebug()<<QString::fromStdString(res)<<endl;
    return QString::fromStdString(res);
}


/*
<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>12345678</CreateTime>
  <MsgType><![CDATA[news]]></MsgType>
  <ArticleCount>1</ArticleCount>
  <Articles>
    <item>
      <Title><![CDATA[title1]]></Title>
      <Description><![CDATA[description1]]></Description>
      <PicUrl><![CDATA[picurl]]></PicUrl>
      <Url><![CDATA[url]]></Url>
    </item>
  </Articles>
</xml>
*/
//回复图文消息
QString MyXml::GetArticlesReplyXml(QString url, QString picurl, int ArticleCount=1, QString Articles="文章", QString Title="文章标题", QString Description="文章描述")
{
    std::string res;
    xml.ShowMyData();
    ClearCreateTime(xml);
    std::string temp1 = xml.Data[5].toStdString();
    std::string temp2 = xml.Data[2].toStdString();
    std::string temp3 = xml.Data[8].toStdString();

    std::string temp6 = Title.toStdString();
    std::string temp7 = Description.toStdString();
    std::string temp8 = url.toStdString();
    std::string temp9 = picurl.toStdString();
    std::string temp10 = Articles.toStdString();

   // std::string temp4 = xml.Data[10].toStdString();
    std::string temp5 = std::to_string(ArticleCount);
    res ="<xml><ToUserName>"+temp1+"</ToUserName>"+"<FromUserName>"+temp2+"</FromUserName>"+"<CreateTime>"+temp3+"</CreateTime>"+"<MsgType><![CDATA[news]]></MsgType><ArticleCount>"+temp5+"</ArticleCount> <Articles><item><Title><![CDATA["+temp6+"]]></Title><Description><![CDATA["+temp7+"]]></Description><PicUrl><![CDATA["+temp9+"]]></PicUrl><Url><![CDATA["+temp10+"]]></Url></item> </Articles></xml>";
    qDebug()<<QString::fromStdString(res)<<endl;
    return QString::fromStdString(res);
}

//点击自动回复
void Widget::on_RobotReply_clicked()
{  if(!ROBOTREPLY)
    {
       ROBOTREPLY = true;
       ui->MsgBox->append("自动回复开启!");
    }else{
        ROBOTREPLY =  false;
        ui->MsgBox->append("自动回复关闭,手动回复开启!!");
    }

}

//手动发送消息
void Widget::on_commandLinkButton_clicked()
{

  this->SendTextMsg(ui->MyReplyText->toPlainText());
}

//机器人发送消息
void Widget::SendRobotMsg()
{
   QString msg,Reply;
   QString MsgType =GetMsgType(xml);
  if(MsgType!="text")
  {
      //除文本外的类型,返回不会的图片
    Reply = xml.GetImgReplyXml("QwYcCLwZag1Q5WWDWwc9wFSsxd0Qo1pUnO2e-kck7HuI1nU9058ZuGaiHqUY5QcO");
  }else{
     //文本消息,去数据库查找当前消息的回复
    msg = xml.GetMsg();//获取消息
    GetMsgFromDataBase(msg);
    MsgType = MyMsg.Data[2];

    if(MsgType=="text")  //文本
    {
         Reply = xml.GetTextReplyXml(MyMsg.Data[3]);
    }else if(MsgType=="image") //图片
    {
       Reply = xml.GetImgReplyXml(MyMsg.Data[3]);
    }else if(MsgType=="video") //视频
    {
        Reply = xml.GetVideoReplyXml(MyMsg.Data[3],MyMsg.Data[4],MyMsg.Data[5]);
    }else if(MsgType=="news") //图文消息
    {

//        Reply = xml.GetArticlesReplyXml(MyMsg.Data[7],MyMsg.Data[8],1,MyMsg.Data[4],MyMsg.Data[5],MyMsg.Data[6]);
        Reply = xml.GetArticlesReplyXml(MyMsg.Data[8],MyMsg.Data[7],1,MyMsg.Data[4],MyMsg.Data[5],MyMsg.Data[6]);
    }else{
        //没有匹配到
      Reply = xml.GetImgReplyXml("QwYcCLwZag1Q5WWDWwc9wFSsxd0Qo1pUnO2e-kck7HuI1nU9058ZuGaiHqUY5QcO");
    }
  }
  this->SendMsg(Reply);
}

//回复消息
void Widget::ToReply()
{
    if(ROBOTREPLY)
    {
       this->SendRobotMsg();
    }else{
      ui->MsgBox->append("<h1 style='color:red;'>您已经开启手动回复模式,请您在输入区域输入内容,手动发送,</h1>");
    }
}
